package net.manelizzard.equipmentexplorer.activity;

import net.manelizzard.equipmentexplorer.R;
import net.manelizzard.equipmentexplorer.util.Constants;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import com.parse.LogInCallback;
import com.parse.Parse;
import com.parse.ParseException;
import com.parse.ParseUser;
import com.parse.SignUpCallback;

/**
 * Activity showing a basic form for Sign In and Sign Up.
 * 
 * It uses Parse (<a href="http://www.parse.com">website</a>) as server.
 * 
 * @author Manel Simon (manelizzard@gmail.com)
 *
 */
public class ActivityLogin extends Activity {
	// Debug TAG
	private final String TAG = "Activity Login";
	
	// UX object references
	private EditText mEditTextEmail;
	private EditText mEditTextPasswd;
	private ProgressDialog mProgressDialog;
	
	// SharedPreferences to remember logged user
	private SharedPreferences mSharedPreferences;
	
	// Flag to detect if activity is stopped (not visible any more)
	private boolean mFlagActivityStopped;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        setContentView(R.layout.activity_login);
        
        // Inits the elements
        init();
        getViews();
    }
    
    @Override
    protected void onStop() {
    		super.onStop();
    		
    		// Flag to be checked after asynchronous validation is done
    		mFlagActivityStopped = true;
    		
    		// Hides the progress dialog if user exists the Activity
    		if(mProgressDialog != null && mProgressDialog.isShowing())
    			mProgressDialog.dismiss();
    }
    
    /**
     * Initializes the Activity elements
     */
    private void init() {
    	
    		/** Parse initialization **/
    		Parse.initialize(this, Constants.PARSE.APP_ID, Constants.PARSE.CLIENT_KEY);
    		
    		/** Shared Preferences **/
    		mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
    		
    		// If is logged, redirect user to "Activity Main"
    		if(mSharedPreferences.getBoolean(Constants.PREFERENCES.LOGGED, false)) {
				// Launch Intent to main activity
				Intent mainIntent = new Intent(ActivityLogin.this, ActivityMain.class);
				startActivity(mainIntent);
    		}
    		
    		mFlagActivityStopped = false;
    }
    
    @Override
    protected void onResume() {
    		super.onResume();
    		
    		// Restores email if exists
    		if(mSharedPreferences != null)
    			mEditTextEmail.setText(mSharedPreferences.getString(Constants.PREFERENCES.USERNAME, ""));
    }
    
    /**
     * Obtain UX object references
     */
    private void getViews() {
    		mEditTextEmail = (EditText) findViewById(R.id.editTextEmail);
    		mEditTextPasswd = (EditText) findViewById(R.id.editTextPasswd);
    		
    		// Progress Dialog init
    		mProgressDialog = new ProgressDialog(this);
    }
    
    /**
     * Handles the click event in the screen buttons
     * 
     * @param v The {@link View} firing the event
     */
    public void onBtnClick(View v) {
    	
    		// Detect the button clicked
    		switch(v.getId()) {
    		
    			/** User clicked "Sign in" button **/
	    		case R.id.btnSignIn:
	    			// If any of the fields is empty, show a message and do nothing else
	    			if(mEditTextEmail.getText().toString().equalsIgnoreCase(Constants.VALIDATION.EMPTY_FIELD)) {
	    				Toast.makeText(this, getString(R.string.toast_err_enter_mail), Toast.LENGTH_LONG).show();
	    			} else if (mEditTextPasswd.getText().toString().equalsIgnoreCase(Constants.VALIDATION.EMPTY_FIELD)) {
	    				Toast.makeText(this, getString(R.string.toast_err_enter_passwd), Toast.LENGTH_LONG).show();
	    			} else {
	    				doSignIn(mEditTextEmail.getText().toString(), mEditTextPasswd.getText().toString());
	    			}
	    			
	    			break;
	    			
	    		/** User clicked "Sign up" button **/
	    		case R.id.btnSignUp:
	    			
	    			// If any of the fields is empty, show a message and do nothing else
	    			if(mEditTextEmail.getText().toString().equalsIgnoreCase(Constants.VALIDATION.EMPTY_FIELD) ||
	    					mEditTextPasswd.getText().toString().equalsIgnoreCase(Constants.VALIDATION.EMPTY_FIELD)) {
	    				Toast.makeText(this, getString(R.string.toast_err_enter_sign_up), Toast.LENGTH_LONG).show();
	    			} else {
	    				doSignUp();
	    			}
	    			
	    			break;
    		}
    }
    
    /**
     * Shows a message to the user corresponding to a String resource
     * 
     * @param resId The String resource to be prompted
     */
    private void showToast(int resId) {
    		Toast.makeText(this, getString(resId), Toast.LENGTH_LONG).show();
    }
    
    /**
     * Does Sign In with provided username and password
     * It uses Parse framework
     * 
     *  @param username The username to be logged in
     * @param passwd The user password (as plain text)
     */
    private void doSignIn(String username, String passwd) {
    	
    		// Stores user email to prevent writing it thousand times
    		if(mSharedPreferences != null)
				mSharedPreferences.edit().putString(Constants.PREFERENCES.USERNAME, username).commit();
    		
    		// Changes progress dialog message or shows it if it is not already diplayed
    		if(mProgressDialog != null) {
    			mProgressDialog.setMessage(getString(R.string.pd_signing_in));
    			
    			if(!mProgressDialog.isShowing())
    				mProgressDialog.show();
    		}
		
    		/**
    		 * Invoques asynchronous login provided by Parse SDK.
    		 * When processing is done, the LogInCallback is called.
    		 */
		ParseUser.logInInBackground(username, passwd, new LogInCallback() {
			
			@Override
			public void done(ParseUser parseUser, ParseException parseException) {
				
				// If activity is not visible any more, do nothing
				if(mFlagActivityStopped)
					return;
				
				if(ActivityLogin.this != null && !ActivityLogin.this.isFinishing()) {
					// Dismiss ProgressDialog
					if(mProgressDialog != null && mProgressDialog.isShowing())
						mProgressDialog.dismiss();	
				}
				
				if (parseUser != null) {
					// Hooray! The user is logged in.
					// Persist LOGGED status
					if(mSharedPreferences != null) {
						mSharedPreferences.edit().putBoolean(Constants.PREFERENCES.LOGGED, true).commit();
					}

					// Launch Intent to main activity
					Intent mainIntent = new Intent(ActivityLogin.this, ActivityMain.class);
					startActivity(mainIntent);
				} else {
					// Signup failed. Look at the ParseException to see what happened.
					Log.e(TAG, "SignIn response: " + parseException.getCode());
					
					// An error occurred
					switch(parseException.getCode()) {
						case ParseException.OBJECT_NOT_FOUND:
							showToast(R.string.toast_err_sign_in_failed);
							break;
							
						case ParseException.INTERNAL_SERVER_ERROR:
							showToast(R.string.toast_err_server_generic);
							break;
							
						case ParseException.TIMEOUT:
							showToast(R.string.toast_err_server_timeout);
							break;
					}
				}
			}
		});
    }
    
    /**
     * Does Sign Up with Parse SDK
     * 
     * Shows a ProgressDialog and calls asynchronously the SignUp Parse SDK util
     */
    private void doSignUp() {
    		if(mProgressDialog != null) {
				mProgressDialog.setMessage(getString(R.string.pd_signing_up));
				mProgressDialog.show();
    		}
    		
    		// Build ParseUser from Parse
    		ParseUser parseUser = new ParseUser();
    		
    		// Sets username and password
    		parseUser.setUsername(mEditTextEmail.getText().toString());
    		parseUser.setPassword(mEditTextPasswd.getText().toString());
    		
    		/**
    		 * Invoques asynchronous sign up provided by Parse SDK.
    		 * When processing is done, the SignUpCallback is called.
    		 */
    		parseUser.signUpInBackground(new SignUpCallback() {
				
				@Override
				public void done(ParseException parseException) {		
					// If activity is not visible any more, do nothing
					if(mFlagActivityStopped)
						return;
					
					if(parseException == null) {
						// Everything went OK. Do SignIn
						doSignIn(mEditTextEmail.getText().toString(), mEditTextPasswd.getText().toString());
					} else {
						// Dismiss ProgressDialog
						if(mProgressDialog != null && mProgressDialog.isShowing())
							mProgressDialog.dismiss();
						
						Log.e(TAG, "SignUp response: " + parseException.getCode());
						
						// An error occurred
						switch(parseException.getCode()) {
							case ParseException.USERNAME_TAKEN:
								showToast(R.string.toast_err_email_taken);
								break;
							case ParseException.INTERNAL_SERVER_ERROR:
								showToast(R.string.toast_err_server_generic);
								break;
							case ParseException.TIMEOUT:
								showToast(R.string.toast_err_server_timeout);
								break;
						}
					}
				}
			});
    }
}
